/* eslint-disable no-await-in-loop */
require('dotenv').config();
const {
  SQSClient, ReceiveMessageCommand, SendMessageBatchCommand, DeleteMessageBatchCommand,
} = require('@aws-sdk/client-sqs');
const { v4: uuidV4 } = require('uuid');
const log = require('../utils/log');

class SQS {
  constructor(config, process = null) {
    this.client = new SQSClient({ region: 'us-west-2' });
    this.config = config;
    this.process = process;
    log.mark('config: ', config);
  }

  async receiveMessageFromQueue(rest = {}) {
    // eslint-disable-next-line no-constant-condition
    while (true) {
      try {
        const params = {
          QueueUrl: this.config.QUEUE_URL,
          MaxNumberOfMessages: this.config.MAX_NUMBER_OF_MESSAGES,
          VisibilityTimeout: this.config.VISIBILITY_TIMEOUT,
          WaitTimeSeconds: this.config.WAIT_TIME_SECONDS,
          ...rest,
        };
        const command = new ReceiveMessageCommand(params);
        const response = await this.client.send(command);

        if (response.Messages) {
          log.info(`Received ${response.Messages.length} messages from queue`);
          if (this.process && this.process instanceof Function) {
            await this.process(response.Messages);
            await this.batchDeleteMessage(response.Messages);
          }
        } else {
          log.warn('No messages received from queue');
        }
      } catch (err) {
        log.error('receiveMessageFromQueue', err);
      }
    }
  }

  async batchDeleteMessage(messages) {
    const Entries = messages.map((item) => ({
      Id: item.MessageId,
      ReceiptHandle: item.ReceiptHandle,
    }));
    const params = {
      QueueUrl: this.config.QUEUE_URL,
      Entries,
    };

    const command = new DeleteMessageBatchCommand(params);
    const response = await this.client.send(command);
    log.info('Deleted message response', response.$metadata.httpStatusCode);
  }

  async batchSendMessage(messages) {
    const params = {
      QueueUrl: this.config.QUEUE_URL,
      Entries: messages.map((body) => (
        {
          Id: uuidV4(),
          MessageBody: body,
        })),
    };

    const command = new SendMessageBatchCommand(params);
    const response = await this.client.send(command);
    return response;
  }
}

module.exports = SQS;
